/*
 * Copyright (c) 2016 Nordic Semiconductor ASA
 * Copyright (c) 2016 Vinayak Kariappa Chettimada
 *
 * SPDX-License-Identifier: Apache-2.0
 */

typedef void (*radio_isr_cb_t) (void *param);

void isr_radio(void);
void radio_isr_set(radio_isr_cb_t cb, void *param);

void radio_setup(void);
void radio_reset(void);
void radio_phy_set(u8_t phy, u8_t flags);
void radio_tx_power_set(s8_t power);
void radio_tx_power_max_set(void);
s8_t radio_tx_power_min_get(void);
s8_t radio_tx_power_max_get(void);
s8_t radio_tx_power_floor(s8_t power);
void radio_freq_chan_set(u32_t chan);
void radio_whiten_iv_set(u32_t iv);
void radio_aa_set(u8_t *aa);
void radio_pkt_configure(u8_t bits_len, u8_t max_len, u8_t flags);
void radio_pkt_rx_set(void *rx_packet);
void radio_pkt_tx_set(void *tx_packet);
u32_t radio_tx_ready_delay_get(u8_t phy, u8_t flags);
u32_t radio_tx_chain_delay_get(u8_t phy, u8_t flags);
u32_t radio_rx_ready_delay_get(u8_t phy, u8_t flags);
u32_t radio_rx_chain_delay_get(u8_t phy, u8_t flags);
void radio_rx_enable(void);
void radio_tx_enable(void);
void radio_disable(void);

void radio_status_reset(void);
u32_t radio_is_ready(void);
u32_t radio_is_done(void);
u32_t radio_has_disabled(void);
u32_t radio_is_idle(void);

void radio_crc_configure(u32_t polynomial, u32_t iv);
u32_t radio_crc_is_valid(void);

void *radio_pkt_empty_get(void);
void *radio_pkt_scratch_get(void);
void *radio_pkt_decrypt_get(void);

void radio_switch_complete_and_rx(u8_t phy_rx);
void radio_switch_complete_and_tx(u8_t phy_rx, u8_t flags_rx, u8_t phy_tx,
				  u8_t flags_tx);
void radio_switch_complete_and_disable(void);

void radio_rssi_measure(void);
u32_t radio_rssi_get(void);
void radio_rssi_status_reset(void);
u32_t radio_rssi_is_ready(void);

void radio_filter_configure(u8_t bitmask_enable, u8_t bitmask_addr_type,
			    u8_t *bdaddr);
void radio_filter_disable(void);
void radio_filter_status_reset(void);
u32_t radio_filter_has_match(void);
u32_t radio_filter_match_get(void);

void radio_bc_configure(u32_t n);
void radio_bc_status_reset(void);
u32_t radio_bc_has_match(void);

void radio_tmr_status_reset(void);
void radio_tmr_tifs_set(u32_t tifs);
u32_t radio_tmr_start(u8_t trx, u32_t ticks_start, u32_t remainder);
u32_t radio_tmr_start_tick(u8_t trx, u32_t tick);
void radio_tmr_start_us(u8_t trx, u32_t us);
u32_t radio_tmr_start_now(u8_t trx);
u32_t radio_tmr_start_get(void);
void radio_tmr_stop(void);
void radio_tmr_hcto_configure(u32_t hcto);
void radio_tmr_aa_capture(void);
u32_t radio_tmr_aa_get(void);
void radio_tmr_aa_save(u32_t aa);
u32_t radio_tmr_aa_restore(void);
u32_t radio_tmr_ready_get(void);
void radio_tmr_end_capture(void);
u32_t radio_tmr_end_get(void);
u32_t radio_tmr_tifs_base_get(void);
void radio_tmr_sample(void);
u32_t radio_tmr_sample_get(void);

void radio_gpio_pa_setup(void);
void radio_gpio_lna_setup(void);
void radio_gpio_lna_on(void);
void radio_gpio_lna_off(void);
void radio_gpio_pa_lna_enable(u32_t trx_us);
void radio_gpio_pa_lna_disable(void);

void *radio_ccm_rx_pkt_set(struct ccm *ccm, u8_t phy, void *pkt);
void *radio_ccm_tx_pkt_set(struct ccm *ccm, void *pkt);
u32_t radio_ccm_is_done(void);
u32_t radio_ccm_mic_is_valid(void);

void radio_ar_configure(u32_t nirk, void *irk);
u32_t radio_ar_match_get(void);
void radio_ar_status_reset(void);
u32_t radio_ar_has_match(void);

/*****************************************************************************
 *DFE
 ****************************************************************************/
#if defined(CONFIG_BT_CTLR_DF_SUBSYSTEM)

/** @brief Sets DFE mode.
 *
 * There are two kinds of DFE: angle of arrival, angle of departure.
 *
 * @param[in] mode	One of following values: @ref RADIO_DFEMODE_DFEOPMODE_AoA,
 * 					@ref RADIO_DFEMODE_DFEOPMODE_AoD
 */
void radio_dfe_mode_set(u8_t mode);

/* @brief Enable parsing of CTEInfo in received packet
 *
 * @param[in] value		True to enable parsing CTEinfo, false otherwise
 */
void radio_cte_inline_ctrl_set(u8_t value);

/** @brief Enable transmission of CTEInfo in S1 byte of PDU Data channel header.
 *
 * @param[in] info		One of following values: @ref RADIO_CTEINLINECONF_CTEINFOINS1_NotInS1,
 * 						@ref RADIO_CTEINLINECONF_CTEINFOINS1_InS1
 */
void radio_cte_infos1_set(u8_t info);

/** @brief Sets number of 8[us] periods the DFE should last.
 *
 * The function sets duration of DFE.
 * Duration is specified by number of 8[us] periods.
 *
 * @param[in] numb_of_8us_periods	Duration of DFE in number of 8us periods
 */
void radio_dfe_numberof8us_set(u8_t numb_of_8us_periods);

/** @brief Sets DFE start point.
 *
 * DFE may be started to broadcast/receive CTE during packet payload or at
 * the end of CRC.
 *
 * @param[in] inextension	One of following values: @ref RADIO_DFECTRL1_DFEINEXTENSION_Payload,
 * 							@ref RADIO_DFECTRL1_DFEINEXTENSION_CRC
 */
void radio_dfe_inextension_set(u8_t inextension);

/** @brief Sets number of steps the gain should be backoff when start of CTE.
 *
 * @param[in] bck_steps		Number of steps to backoff gain
 */
void radio_dfe_backoff_gain_set(u8_t bck_steps);

/** @brief Enables sampling of CTE when CRC error occurs.
 *
 * Samples by default are gathered only when CRC of a received packet is correct.
 * In case of error, samples are not gathered. It is possible to take and store
 * samples even in case when CRC is wrong.
 *
 * @param[in] error_handling	True to enable sampling when CRC error, false otherwise
 */
void radio_cte_error_handling_set(u8_t error_handling);

/** @brief Sets sample spacing in antenna switching period.
 *
 * Following values may be provided:
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACING_4us 4us
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACING_2us 2us
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACING_1us 1us
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACING_500ns 0.5us
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACING_250ns 0.25us
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACING_125ns 0.125us
 *
 * @param[in] spacing	Spacing provided by one of values mentioned above.
 */
void radio_dfe_tsamplespacing_set(u8_t spacing);

/** @brief Sets sample spacing in reference period.
 *
 * Following values may be provided:
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACINGREF_4us 4us
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACINGREF_2us 2us
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACINGREF_1us 1us
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACINGREF_500ns 0.5us
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACINGREF_250ns 0.25us
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACINGREF_125ns 0.125us
 *
 * @param[in] spacing	Spacing provided by one of values mentioned above.
 */
void radio_dfe_tsamplespacingref_set(u8_t spacing);

/** @brief Sets sampling type.
 *
 * Sampling type means kind of data structure used to provide samples:
 * - IQ samples (@ref RADIO_DFECTRL1_SAMPLETYPE_IQ)
 * - magnitude/phase samples (@ref RADIO_DFECTRL1_SAMPLETYPE_MagPhase)
 *
 * @param[in] sampletype	Type of samples to be provided.
 */
void radio_dfe_sampletype_set(u8_t sampletype);

/** @brief Sets offset value after end of guard period before starting sampling.
 *
 * The setting allows to do some fine tuning of start point of sampling. The
 * delay is added before first sample in reference period.
 *
 * Minimum possible value is @ref DFE_SAMPLE_OFFSET_MIN, maximum possible
 * value is @ref DFE_SAMPLE_OFFSET_MAX.
 *
 * @param[in] sampleoffset		Number between: @ref DFE_SAMPLE_OFFSET_MIN, @ref DFE_SAMPLE_OFFSET_MAX
 */
void radio_dfe_tsampleoffset_set(s16_t sampleoffset);

/** @brief Sets offset value after end of CRC before starting antenna switching.
 *
 * The setting allows to do some fine tuning of antenna switching start point.
 * The delay is added before start of guard period (switch from idle antenna
 * to first one, reference antenna).
 *
 * Minimum possible value is @ref DFE_SWITCH_OFFSET_MIN, maximum possible
 * value is @ref DFE_SWITCH_OFFSET_MAX.
 *
 * @param[in] switchoffset		Number between: @ref DFE_SWITCH_OFFSET_MIN, @ref DFE_SWITCH_OFFSET_MAX
 */
void radio_dfe_tswitchoffset_set(s16_t switchoffset);

/** @brief Sets antenna switch spacing.
 *
 * Following values may be provided:
 *  - @ref RADIO_DFECTRL1_TSWITCHSPACING_4us 4us
 *  - @ref RADIO_DFECTRL1_TSWITCHSPACING_2us 2us
 *  - @ref RADIO_DFECTRL1_TSWITCHSPACING_1us 1us
 *
 * @param[in] spacing	Spacing provided by one of values mentioned above.
 */
void radio_dfe_tswitchspacing_set(u8_t spacing);

/** @brief Antenna switching GPIO structure
 */
struct dfe_gpio {
	/** index of the DFE slot where to place the GPIO */
	u8_t reg_idx;
	/** GPIO descriptor that consists of port and GPIO number.
	 * This is a 6 bit value: 0-4 bits are GPIO number, 5th bit is
	 * post number [0,1].
	 * */
	u8_t gpio_num;
};

/** @brief Sets GPIOs that may be used by radio to process antenna switching.
 *
 * There is up to 8 possible slots to set GPIOS to be used for antenna switching.
 * Each GPIO is a "single bit" to be used to address (enable/disable) particular
 * antenna.
 * GPIOs are provided as array. The length of the array must be in range [1-8].
 *
 * @param[in] gpip		Pointer to array of GPIOs
 * @param[in] len		Length of the array
 */
void radio_dfe_gpio_set(const struct dfe_gpio *gpio, u8_t length);

/** @brief Unsets GPIOs from DFE module.
 *
 * Provided GPIOs are set into disconnected state in DFE module.
 * GPIOs to unset are provided as array.
 * The length of the array must be in range [1-8].
 * GPIOs are unset according to indices provided in the array.
 *
 * @param[in] gpip		Pointer to array of GPIOs
 * @param[in] len		Length of the array
 */
void radio_dfe_gpio_unset(const u8_t *gpio, u8_t length);

/** @brief Sets GPIO patterns to enable particular antennas during DFE.
 *
 * Patterns are applied during antenna switching.
 * Each pattern is applied as binary value to GPIOS configured
 * by @ref radio_dfe_gpio_set. So each bit of pattern is mapped to a GPIO.
 * There is up to 40 antenna patterns that may be configured.
 * The minimum required number of patterns is 3: idle pattern,
 * guard + reference periods, switching period.

 * @param[in] switching			Array of patterns to be used in switching period
 * @param[in] switching_len		Number of patterns in @p switching array.
 * 							Max possible is 38 (40 - 2 for idle and reference).
 */
void radio_dfe_switch_patterns_set(const u8_t *patterns, u8_t length);

/** @brief Provides current frequency value.
 *
 * The frequency provided includes carrier frequency.

 * @return Current frequency value
 */
u16_t radio_dfe_frequency();

/** @biref Sets buffer for IQ samples.
 *
 * The function is responsible for setting a buffer where IQ samples will be stored.
 * Size of a buffer is a number of words that may be stored in a buffer.
 * The data are stored with use of DMA.
 *
 * @param[in] buffer	memory buffer for IQ samples
 * @param[in] words_num	number of words that may be stored in buffer
 */
void radio_dfe_samples_buffer_set(void * buffer, u16_t words_num);

/** @brief Provides number of samples gathered by radio
 *
 * @return Number of samples stored by radio
 */
u32_t radio_dfe_get_recv_sampl_num();

#endif /* CONFIG_BT_CTLR_DF_SUBSYSTEM */
